Modular DTD’s

Now that you are creating external DTD’s, let’s take a step further and use multiple external DTD’s.  This is concept is known as modular DTD’s.  As we mentioned before, DTD’s can get quite complex in nature.  Often, it is a good idea to break them up into pieces.  Another advantage is that you can create a series of reusable component DTD’s that you can include at will.

The following code uses a parameter entity to include an external DTD in the document.  This in turn includes the contents of the external entity.  Look at the following code.

<!-- Company Titles -->
<!ENTITY pos.ceo 	"CEO">
<!ENTITY pos.president 	"President">
<!ENTITY pos.vicepresident 	"Vice President">
<!ENTITY pos.projectManager 	"Project Manager">
<!ENTITY pos.sales	"Sales">
<!ENTITY pos.programmer 	"Programmer">
<!ENTITY pos.analyst	"Systems Analyst">

File: Chapter 6\EmployeeTitles.dtd

This new DTD defines the titles of the positions within the company (at least a subset thereof for our example) and declares them as entities.  We can then use these entities in our document content.  Instead of typing the actual title in each <position> element, we can use the corresponding entity.  This is useful because if a title ever changes (e.g. “Programmer” changes to “Software Developer”) we can change it in one place and it has a trickle down effect into all of the XML documents that reference it.  Let’s look at the new employees XML document that uses the code.  The lines to pay close attention to have been bolded.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE employees SYSTEM "Employees2.dtd" [

<!ENTITY % EmployeeTitles SYSTEM 
		  "EmployeeTitles.dtd">
%EmployeeTitles;
]>

<employees>

    <employee id="A1234">
        <name>
            <first>John</first>
            <last>Doe</last>
        </name>
        <position>&pos.programmer;</position>
        <address>
            <street>123 Main Street</street>
            <city>Anywhere</city>
            <state>CA</state>
            <zip>92000</zip>
        </address>
        <phone>
            <main>(714) 555-1000</main>
            <fax>(714) 555-1001</fax>
        </phone>
    </employee>

    <employee id="A2345">
        <name>
            <first>Jane</first>
            <last>Doe</last>
        </name>
        <position>&pos.analyst;</position>
        <address>
        </address>
        <phone>
            <main>(714) 555-2000</main>
            <mobile>(949) 555-2200</mobile>
            <home>(949) 555-2220</home>
        </phone>
    </employee>
</employees>

File: Chapter 6\Employees4.xml

Notice the output when we view the XML document in Internet Explorer.

File: Chapter 6\Employees4.xml in IE5 (the <name>, <address>, and <phone> elements are retracted to lesson the screen size).

There are a couple of points that need to be stressed about this document.  The first is the XML processing instruction.

<?xml version="1.0" standalone="no"?>

The “standalone” attribute has been set to “no”, because this is no longer a standalone document.  We are now reliant on EmployeeTitles.dtd so that the document can be processed correctly.  If it cannot be found, errors are generated because it cannot expand the “position” entities.

The second point is the actual inclusion of the external DTD.  Let’s look at the syntax.  

<!ENTITY % EmployeeTitles SYSTEM 
		     "EmployeeTitles.dtd">
%EmployeeTitles;

We already are using an external DTD in our XML document and it is specified in the document type declaration statement.  This being the case, we have to include the file in another way.  We declared a parameter entity containing the name of the external DTD and immediately referenced it.  This is the most common way of doing it.  

Finally, let’s look at the <position> elements for our employees.  Notice that we are able to use the “position” entities directly inside of the markup as if they were declared internally.

. . . (omitted)
<position>&pos.programmer;</position>
. . . (omitted)
<position>&pos.analyst;</position>
. . . (omitted)

Warning:	Be really careful when you start using a modular 
	approach to your DTD’s.  First of all, you need to 
	understand what you are including and how it might 
	affect and/or conflict with your internal subset as 
	well as other external subsets.  

	Also, be careful of including documents that include 
	other documents that include other documents, etc.  
	You can quickly end up including a large amount of 
	stuff that you did not expect.